//class for show queries function, by Fransiska Putri Wina
#include <iostream>
#include <algorithm>
#include "Menu_Show_Queries.h"

using namespace std;

//default constructor
Menu_Show_Queries::Menu_Show_Queries() {}

//Procedure for solving B1a problem, by Fransiska Putri Wina
void Menu_Show_Queries::B1a(vector<Menu_Item> menu_items,vector<Recipe> recipes,vector<Ingredient> ingredients) {
	 /* The following code has been written by Fransiska Putri Wina, solving problem B1a */
	
	 cout << "\nPrint a menu item recipe\n\n";
	 string item;
	 int index = -1;
	 int i=0;
	 int recipeid;
	 
	 cout << "Which menu item would you like to see its recipe \n>> ";
	 cin >> item;
	 
	 for(i = 0; i < menu_items.size(); i++) {
		if(menu_items[i].get_menu_item_name() == item) {
		   index = i;
		   break;
		}
	 }
	 
	 if(index==-1) {
		cout << "Apologies, there does not appear to be an item bearing that name.\n\n";
	 }
	 else {
		recipeid = menu_items[index].recipeID();
		cout << "Here is the recipe of " << menu_items[index].get_menu_item_name()<< ": \n\n";
		cout <<  menu_items[index].get_descr() << "\n\n";
		cout << "Ingredients : \n";
		for (int i=0; i < ingredients.size(); i++) {
		   if (ingredients[i].get_recipe_id() == recipeid) {
			  ingredients[i].displayaun();
		   }
		}
		cout << endl;
		cout << "Instructions : \n";
		for (int i=0; i < recipes.size(); i++) {
		   if (recipes[i].recipeId() == recipeid) {
			  recipes[i].displayins();
		   }
		}
		cout << endl;
	 }
	 /* End of code written by FPW */
}


/* MGM B.1 b: START */
//sort recipe based on chef
bool sortChef(const Recipe& left, const Recipe& right)
{
   return left.chefName() < right.chefName();
}
/* MGM B.1 b: END */

//procedure for solving B1b problem, by Muhammad Ghufron Mahfudhi
void Menu_Show_Queries::B1b(vector<Menu_Item> vMenuItem, vector<Recipe> vRecipe)
{
	/* print all menu items sorted by chef (MGM B.1 b: START) */
	cout << "\nPrint all menu items sorted by Chef\n\n";
	string menu[4][vMenuItem.size()+1];
	menu[0][0] = " Chef Name";
	menu[1][0] = " Menu Item";
	menu[2][0] = " ID";
	menu[3][0] = " Price";
	 
	//sorting recipes
	vector<Recipe> tempRecipe = vRecipe;
	sort(tempRecipe.begin(), tempRecipe.end(), sortChef);
	//sorting menu items
	vector<Menu_Item> tempMenu;
	vector<string> chefName;
	for(int i = 0; i < tempRecipe.size(); i++)
	{
		vector<int> index;
		for(int j = 0; j < vMenuItem.size(); j++)
		{
		   if(vMenuItem[j].recipeID() == tempRecipe[i].recipeId())
		   {
			  index.push_back(j);
		   }
		}
		if(index.size() != 0)
		{
		   for(int k = 0; k < index.size(); k++)
		   {
			  tempMenu.push_back(vMenuItem[index[k]]);
			  chefName.push_back(tempRecipe[i].chefName());
		   }
		}
	}
	if(tempMenu.size() != 0 && tempMenu.size() == vMenuItem.size())
	{
		for(int i = 0 ; i < tempMenu.size(); i++)
		{
		   stringstream ss1, ss2;
		   menu[0][i+1] = " " + chefName[i];
		   menu[1][i+1] = " " + tempMenu[i].get_menu_item_name();
		   ss1 << " " << tempMenu[i].menuItemId();
		   menu[2][i+1] = ss1.str();
		   ss2 << " $" << tempMenu[i].getPrice();
		   menu[3][i+1] = ss2.str();
		}
	}
			  
	//print menu items
	for(int i = 0; i < 4; i++)
	{
		cout << "|";
		for(int j = 0; j < 18; j++)
		{
		   cout << "-";
		}
	}
	cout << "|\n";
	for(int i = 0; i < vMenuItem.size()+1; i++)
	{
		for(int j = 0; j < 4; j++)
		{
		   cout << "|";
		   cout << menu[j][i];
		   int len = 18 - menu[j][i].size();
		   for(int k = 0; k < len; k++)
		   {
			  cout << " ";
		   }
		   
		}
		cout << "|\n";
		if(i == 0 || i == vMenuItem.size())
		{
		   for(int j = 0; j < 4; j++)
		   {
			  cout << "|";
			  for(int k = 0; k < 18; k++)
			  {
				 cout << "-";
			  }
		   }
		   cout << "|\n";
		}
		else
		{
		   for(int j = 0; j < 4; j++)
		   {
			  cout << "|";
			  for(int k = 0; k < 18; k++)
			  {
				 cout << " ";
			  }
		   }
		   cout << "|\n";
		}
		
	}
	cout << endl << endl;
	/* print all menu items sorted by chef (MGM B.1 b: END) */
}

//Procedure for solving B1c problem, by Fransiska Putri Wina
void Menu_Show_Queries::B1c(vector<Menu_Item> menu_items,vector<Category> categories) {
	 cout << "\nprint all menu items in a given category sorted by price\n\n";
	 /* The following code has been written by Fransiska Putri Wina, solving problem B1c */
	
	 int i;
	 string cat;
	 int catid;
	 int index=-1;
	 type_b1c menu;
	 vector<type_b1c> menu_item_cat;
	 
	 cout << "Please input your desired category :\n>>";
	 cin >> cat;
	 for(i = 0; i < categories.size(); i++) {
		   if(categories[i].get_cat_name() == cat) {
			  index = i;
			  break;
		   }
		}
	 if (index == -1) {
		cout << "Apologies, there does not appear to be a category bearing that name.\n\n";
	 }
	 else {
		cout << "Here is the menu item in category " << cat << " sorted ascending by price:\n\n";
		catid = categories[i].get_cat_id();
		for(i = 0; i < menu_items.size(); i++) {
		   if(menu_items[i].get_cat_id() == catid) {               
			  //add new item to vector menu_item_cat for further use (sorting)
			  menu.item_name = menu_items[i].get_menu_item_name();
			  menu.price = menu_items[i].getPrice();
			  menu.description = menu_items[i].get_descr();
			  //Menu_Item menu (menu_items[i].get_menu_item_id(), catid, menu_items[i].recipeID(), menu_items[i].get_menu_item_name(), menu_items[i].getPrice(), menu_items[i].get_descr());
			  menu_item_cat.push_back(menu);
		   }
		}
		
		//sorting menu item in given category by price ascending
		sort (menu_item_cat.begin(), menu_item_cat.end());
		for (i=0; i < menu_item_cat.size(); i++) {
		   cout << menu_item_cat[i].description << endl << "price: " << menu_item_cat[i].price << "\n\n";
		}
	 }
	 /* end of code by FPW, B.1c */
}


//Procedure for solving C1a problem, by Fransiska Putri Wina
void Menu_Show_Queries::C1a(vector<Order> vorder, vector<Order_Item> vorder_item,vector<Menu_Item> vmenu_item) {
	cout << "\nPrint all order IDs and tab price sorted by date\n\n";
	/* The following code has been written by Fransiska Putri Wina, solving problem C.1a */

	int i,j; //iterator
	int len=19;
	int order_id;
	int menu_item_id;
	int menu_item_qty;
	double price;
	bool found;
	type_c1a order_cost;
	vector<type_c1a> vorder_cost;
	
	//fill vorder_cost according to vorder
	for(i = 0; i < vorder.size(); i++) {
		order_cost.order_id = vorder[i].getOrderID();
		order_cost.order_date = vorder[i].getOrderDate();
		order_cost.price = 0;
		vorder_cost.push_back(order_cost);
		}
	
	for (i = 0; i < vorder_item.size(); i++) {
		order_id = vorder_item[i].getOrderID();
		menu_item_id = vorder_item[i].getMenuItemID();
		menu_item_qty = vorder_item[i].getProdQty();
		
		//get the price of menu_item included in order_item
		j = 0;
		found = false;
		do {
			if (menu_item_id == vmenu_item[j].get_menu_item_id()) {
				price = vmenu_item[j].getPrice() * menu_item_qty;
				found = true;
			}
			j++;
		} while (j < vmenu_item.size() && !found);
		
		//sum up the price of order item
		j=0;
		found = false;
		do {
			if (order_id == vorder_cost[j].order_id) { //if order_id match, sum up the price
				vorder_cost[j].price = vorder_cost[j].price + price;
				found = true;
			}
			j++;
		} while (j < vorder_cost.size() && !found);
		
	}
	
	
	//sorting order cost by date ascending
	sort (vorder_cost.begin(), vorder_cost.end());
	
	cout << "------------------------------------------------------------" << endl;
	cout << "|Order ID           |Date               |Tab Price          |" << endl;
	cout << "------------------------------------------------------------" << endl;
	for (i=0; i < vorder_cost.size(); i++) {
		cout << "|" << vorder_cost[i].order_id;
		//convert order_id into string
		ostringstream strs;
		strs << vorder_cost[i].order_id;
		string str = strs.str();
		for (j=0; j < len - str.size(); j++) {
				cout << " ";
			}
		cout << "|";
		
		//convert date into string
		stringstream sstm;
		sstm << vorder_cost[i].order_date.year() << "-"<< vorder_cost[i].order_date.month() << "-" << vorder_cost[i].order_date.day();
		string date = sstm.str();
		cout << date;
		for (j=0; j < len - date.size(); j++) {
				cout << " ";
			}
		cout << "|$";
		
		cout << vorder_cost[i].price;
		//convert price into string
		ostringstream strs2;
		strs2 << vorder_cost[i].price;
		str = strs2.str();
		for (j=0; j < len - str.size()-1; j++) {
				cout << " ";
			}
		cout << "|" << endl;
	}
	cout << "------------------------------------------------------------" << endl;
	cout << endl;
		
	/* end of code by FPW, C.1a */
}

//Procedure for solving C.1b problem, by Fransiska Putri Wina
void Menu_Show_Queries::C1b(vector<Order> vorder, vector<Order_Item> vorder_item,vector<Menu_Item> vmenu_item) {
	cout << "\nprint all menu items in a given order sorted by price based on quantitiy\n\n";
	/* The following code has been written by Fransiska Putri Wina, solving problem C.1b */

	int i,j; //iterator
	int len=19;
	bool is_order_id_exist=false;
	bool found;
	int order_id;
	int menu_item_id;
	int menu_item_qty;
	string menu_item_name;
	double price;
	type_c1b menu_price;
	vector<type_c1b> vmenu_price;
	
	
	cout << "Please input your desired order ID :\n>>";
	cin >> order_id;
		
	i = 0;
	found = false;
	do {
		if(vorder[i].getOrderID() == order_id) {
				found = true;
			}
		i++;
	} while (i < vorder.size() && !found);
		
	if (!found) {
		cout << "Apologies, there does not appear to be an order id bearing that number.\n\n";
	}
	else {
		//group the menu item within the order id based on menu item id
		for (i = 0; i < vorder_item.size(); i++) {
			if (order_id == vorder_item[i].getOrderID()) {

				menu_item_id = vorder_item[i].getMenuItemID();
				menu_item_qty = vorder_item[i].getProdQty();
				
				//get the menu item name and price * quantity
				j = 0;
				found = false;
				do {
					if (menu_item_id == vmenu_item[j].get_menu_item_id()) {
						menu_item_name = vmenu_item[j].get_menu_item_name();
						price = vmenu_item[j].getPrice() * menu_item_qty;
						found = true;
					}
					j++;
				} while (j < vmenu_item.size() && !found);
				
				//check -- has the vmenu_price already contained item with the same menu_item_name?				
				j=0;
				found = false;
				while (j < vmenu_price.size() && !found) {
					if (menu_item_name == vmenu_price[j].menu_item_name) { //yes, sum the price
						vmenu_price[j].price = vmenu_price[j].price + price;
						found = true;
					}
					j++;
				} 
				
				if (!found) {//no, push back the item into vmen_price
					menu_price.menu_item_name = menu_item_name;
					menu_price.price = price;
					vmenu_price.push_back(menu_price);
				}
			}
			
		}
		
		//sort the menu_price by price ascending
		sort (vmenu_price.begin(), vmenu_price.end());
		
		cout << "Here is the menu item in order id " << order_id << " sorted ascending by price:\n\n";
		cout << "----------------------------------------" << endl;
		cout << "|Menu Item Name     |Price Based on Qty |" << endl;
		cout << "----------------------------------------" << endl;
		for (i=0; i < vmenu_price.size(); i++) {
			cout << "|" << vmenu_price[i].menu_item_name;
			for (j=0; j < len - vmenu_price[i].menu_item_name.size(); j++) {
				cout << " ";
			}
			cout << "|$" << vmenu_price[i].price;
			
			//convert price to string
			ostringstream strs;
			strs << vmenu_price[i].price;
			string str = strs.str();
			
			for (j=0; j < len - str.size()-1; j++) {
				cout << " ";
			}
			cout << "|" << endl;
		}
		cout << "----------------------------------------" << endl;
		cout << endl;
	}
	/* end of code by FPW, C.1b */
}



